#include "XTcpClient.h"
#include "XThreadPool.h"
#include <iostream>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <event2/thread.h>

using namespace std;

XTcpClient::XTcpClient(int threadCount)
{
    m_threadCount = threadCount;

    /**
     * 多线程环境下没有调用evthread_use_windows_threads或evthread_use_pthreads函数
     * 会导致event_base_dispatch函数一直阻塞，(本demo分为主线程和dispatch线程)
     * 即使调用了event_base_loopbreak或event_base_loopexit
     * 也无法让event_base_dispatch退出事件循环。
     */
    evthread_use_pthreads();
}

bool XTcpClient::construct()
{
    bool ret = true;
    if(!m_isRunning)
    {
        ret = ret && XThreadPool::GetInstance()->Init(m_threadCount);

        /* 创建libevent的上下文 */
        m_base = event_base_new();
        if (!m_base)
        {
            cout << "event_base_new  error!" << endl;
        }

        /* 创建IO线程 */
        if(pthread_create(&m_threadID, NULL, PollThread, this) != 0)
        {
            cout << __FILE__<<":"<<__LINE__<<" pthread_create failed!" << endl;
            m_isRunning = false;
        }
        m_isRunning = true;
    }

    return ret;
}

XTcpClient* XTcpClient::NewInstance(int threadCount)
{
    XTcpClient * ret = new XTcpClient(threadCount);
    if((ret == NULL)||!ret->construct())
    {
        delete ret;
        ret = NULL;
    }
    return ret;
}

bool XTcpClient::addTask(XTask *task)
{
    XThreadPool::GetInstance()->Dispatch(task);
}

void* XTcpClient::PollThread(void *arg)
{
    XTcpClient* pthis = (XTcpClient*)arg;
    if(pthis->m_base)
    {
        event_base_dispatch(pthis->m_base);
    }

    if(pthis->m_base)
    {
        event_base_free(pthis->m_base);
    }

    cout<<"exit form io thread"<<endl;
    return NULL;
}

XTcpClient::~XTcpClient()
{
    void *thrdRet = NULL;

    if(m_isRunning)
    {
        event_base_loopbreak(m_base);
        pthread_join(m_threadID, &thrdRet);
        m_isRunning = false;
    }
}
